home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2.0 - Programmer's Utilities Power Pack / Delphi 2.0 Programmer's Utilities Power Pack.iso / s_to_z / tpack / debug.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-09-15  |  9.5 KB  |  331 lines

  1. unit Debug;
  2.  
  3. {the Debug component has been activate in the demo so you'd find
  4. your way here. this component still contains some earlier code to
  5. route the log to an ini file and or the printer. you should find
  6. these useful where appropriate. remember the debug controlling flags
  7. can be set at any time using a call to AdjustDebugFlags. route text
  8. to the trace window using DebugLog}
  9.  
  10. interface
  11.  
  12. uses
  13.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  14.   Forms, Dialogs, StdCtrls, Buttons, Toolbar, ExtCtrls;
  15.  
  16. type
  17.   TDebugDlg = class(TForm)
  18.     Toolbar1: TToolbar;
  19.     ToolButton1: TToolButton;
  20.     Toolbar2: TToolbar;
  21.     Memo1: TMemo;
  22.     procedure ToolButton1Click(Sender: TObject);
  23.   private
  24.     { Private declarations }
  25.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  26.   public
  27.     { Public declarations }
  28.   end;
  29.  
  30.  
  31.   TDebugExtendedComponentOptions = (decEnabled, decDesign
  32.                                   , decCreate, decDestroy, decLoaded, decUpdate
  33.                                   , decInsert, decRemove
  34.                                   , decPrint, decFile, decNotePad );
  35.  
  36.   TDebugExtendedComponentStates =  (decActive,decFormError,decDestroying
  37.                                    ,decPrintSet,decPrinting,decPrintError
  38.                                    ,decFiling,decFileError );
  39.  
  40.   TDebugExtendedComponentFlags = set of TDebugExtendedComponentOptions;
  41.   TDebugExtendedComponentState = set of TDebugExtendedComponentStates;
  42.  
  43.  
  44. {using the flags and log procedure other parts of the app can use debugging services.}
  45.  
  46. procedure DebugLog(Owner:TComponent;const Text:String); export;
  47.  
  48. procedure AdjustDebugFlags(Value:TDebugExtendedComponentFlags); export;
  49.  
  50. {procedure StartNotePad;}
  51.  
  52. const
  53.   DebugFlags:TDebugExtendedComponentFlags = [];
  54.   DebugState:TDebugExtendedComponentState = [];
  55.  
  56. implementation
  57.  
  58. uses
  59.   IniFiles, PasUtils;
  60.  
  61. const
  62.   DebugLogName= '\debuglog.ini';
  63.  
  64. var
  65.   DebugFile: TIniFile;
  66.   DebugPrinter: TextFile;
  67.  
  68. var
  69.   DebugDlg: TDebugDlg;
  70.  
  71. {$R *.DFM}
  72.  
  73. procedure DebugLog(Owner:TComponent;const Text:String);
  74. const
  75.   BufSize=144;
  76.   Count:Longint=0;
  77.   indent:Byte=0;
  78. var
  79.   Buffer:PChar;
  80.   offset:byte;
  81.   txt:string;
  82.  
  83.   procedure tOut(const Text:String);
  84.   begin
  85.     try
  86.       DebugDlg.Memo1.Lines.add(Text);
  87.     except {ignore?}
  88.       end;
  89.   end;
  90.  
  91. begin
  92.  
  93.   if not (decEnabled in DebugFlags) or (decDestroying in DebugState) then
  94.     exit;
  95.  
  96.   if not ((decFormError in DebugState) or (decActive in DebugState)) then
  97.     if not (decFormError in DebugState) then begin
  98.       if DebugDlg=nil then
  99.         DebugDlg:= TDebugDlg.Create(nil)
  100.       else {take our chances on the form really really being there already!}
  101.         ;
  102.       try
  103.         with DebugDlg do begin
  104.           with Memo1.Lines do begin
  105.             Clear;
  106.             Add('Opened '+datetimetostr(now));
  107.             end;
  108.           OnClose:=FormClose;
  109.           Show;
  110.           Update;
  111.           end;
  112.       except
  113.         DebugState:=DebugState+[decFormError];
  114.         raise;
  115.         end;
  116.       DebugState:=DebugState+[decActive]
  117.       end;
  118.  
  119.   if Owner<>nil then
  120.     if csDesigning in Owner.ComponentState then
  121.       if not (decDesign in DebugFlags) then
  122.         exit;
  123.  
  124. {  if (pos('.DCL',paramstr(0))>0) then {do nothing inside library!}
  125. {    if (pos('Create',Text)>0) then
  126.     exit;}
  127.  
  128.   case Text[1] of
  129.   '+',
  130.   '-': offset:=2;
  131.   else
  132.     offset:=1;
  133.   end;
  134.   Count:=Count+1;
  135.   if Text[1] = '-' then
  136.     indent:=indent-2;
  137.  
  138.   txt:=copy(text,offset,255);
  139.   if owner<>nil then
  140.     Txt:=owner.classname+': '+txt;
  141.   tOut(inttostr(Count)+'. '+Spaces(Indent)+txt);
  142.   {}
  143.   if not (decPrintError in DebugState) and (decPrint in DebugFlags) then begin
  144.     if not (decPrinting in DebugState) then
  145.  
  146.       raise
  147.         exception.create('WINPRN must be linked to debug.pas for printing');
  148.  
  149.       {e.g. add 'WINPRN' to the uses clause at the top of the file
  150.        remove/comment out the exception above
  151.        and uncomment the block below.
  152.        WinPrn is originally stored as in \DELPHI\SOURCE\RTL\WIN\WINPRN}
  153.  
  154. {
  155.       try
  156.         AssignDefPrn(DebugPrinter);
  157.         GetMem(Buffer,BufSize);
  158.         TitlePrn(DebugPrinter,StrPCopy(Buffer,'Debugging '+paramstr(0)));
  159.         FreeMem(Buffer,BufSize);
  160.         Rewrite(DebugPrinter);
  161.         DebugState:=DebugState+[decPrinting];
  162.       except on E: Exception do begin
  163.         DebugState:=DebugState+[decPrintError];
  164.         tOut('ERROR printing! '+E.Message);
  165.         end;
  166.         end;
  167. }
  168.     if not (decPrintError in DebugState) then
  169.       writeln(DebugPrinter
  170.        ,inttostr(Count)+'. '+Spaces(Indent)+txt);
  171.     end;
  172.  
  173.   if not (decFileError in DebugState) and (decFile in DebugFlags) then begin
  174.     if not (decFiling in DebugState) then
  175.       try
  176.         DebugFile:=TIniFile.Create(DebugLogName);
  177.         DebugFile.EraseSection(paramstr(0));
  178.         DebugFile.Free;
  179.         DebugState:=DebugState+[decFiling];
  180.       except on E: Exception do begin
  181.         tOut('ERROR erasing section! '+E.Message);
  182.         DebugState:=DebugState+[decFileError];
  183.         end;
  184.         end;
  185.     if (decFiling in DebugState) then
  186.       try
  187.         DebugFile:=TIniFile.Create(DebugLogName);
  188.         DebugFile.WriteString(paramstr(0),IntToStr(Count),'.'+Spaces(Indent)+txt);
  189.         DebugFile.Free;
  190.       except on E: Exception do begin
  191.         tOut('ERROR writing string! '+E.Message);
  192.         DebugState:=DebugState+[decFileError];
  193.         end;
  194.         end;
  195.     end;
  196.   {}
  197.   if Text[1] = '+' then
  198.     indent:=indent+2;
  199.  
  200. end;
  201.  
  202. {}
  203.  
  204. procedure StartNotePad; {could instantiate a shell, but let be simple here.}
  205. const
  206.   BufSize=144;
  207. var
  208.   Buffer:PChar;
  209. begin
  210.   GetMem(Buffer,BufSize);
  211.   WinExec(StrPCopy(Buffer,'Notepad '+DebugLogName),sw_ShowNormal);
  212.   FreeMem(Buffer,BufSize);
  213. end;
  214.  
  215. {}
  216.  
  217. procedure AdjustDebugFlags(Value:TDebugExtendedComponentFlags);
  218. begin
  219.   if not (decPrint in Value) and (decPrint in DebugFlags) then  {print off}
  220.     if (decPrinting in DebugState) then begin
  221.       CloseFile(DebugPrinter);
  222.       DebugState:=DebugState-[decPrinting];
  223.       end;
  224.  
  225.   if not (decFile in Value) and (decFile in DebugFlags) then  {file off}
  226.     if (decFiling in DebugState) then begin
  227.       DebugState:=DebugState-[decFiling];
  228.       if (decNotePad in DebugFlags) then
  229.         StartNotePad;
  230.       end;
  231.  
  232.   if not (decEnabled in Value) and (decEnabled in DebugFlags) then begin{turn all off}
  233.     Value:=Value-[decCreate,decDesign,decDestroy,decLoaded,decUpdate,decInsert,decRemove];
  234.     end;
  235.   if (decEnabled in Value) and not (decEnabled in DebugFlags) then begin{turn all on}
  236.     Value:=Value+[decCreate,decDesign,decDestroy,decLoaded,decUpdate,decInsert,decRemove];
  237.     end;
  238.  
  239.   DebugFlags:=Value;
  240. end;
  241.  
  242.  
  243. {-----------------------------------------------------------------------------------------}
  244. {                                                                                         }
  245. {-----------------------------------------------------------------------------------------}
  246.  
  247. procedure TDebugDlg.FormClose(Sender: TObject; var Action: TCloseAction);
  248. begin
  249.   Action:=caFree;
  250.   DebugDlg:=nil;
  251.   {DebugState:=DebugState-[decActive];}
  252.   DebugState:= [];
  253. end;
  254.  
  255. procedure TDebugDlg.ToolButton1Click(Sender: TObject);
  256. begin
  257.   Close;
  258. end;
  259.  
  260.  
  261. {-----------------------------------------------------------------------------------------}
  262. { INITIALIZATION AND EXIT PROCEDURES                                                      }
  263. {-----------------------------------------------------------------------------------------}
  264.  
  265. procedure InitializeUnit;
  266. var
  267.   i:integer;
  268.   a:string;
  269. begin
  270.   DebugFlags:= [];
  271.   DebugState:= [];
  272.  { if csDesigning in ComponentState then exit;}
  273.   {process the commandline to set the unit's globals to the desired DEBUG state.}
  274.   for i:=1 to ParamCount do begin
  275.     a:=uppercase(ParamStr(i));
  276.     if copy(a,1,2)='/D' then begin
  277.       DebugFlags:=DebugFlags+[decEnabled];
  278.       if Length(a)=2 then
  279.         DebugFlags:=DebugFlags+[decCreate,decDesign,decDestroy,decLoaded,decUpdate,decInsert,decRemove]
  280.       else begin
  281.         if pos('C',a)>0 then DebugFlags:=DebugFlags+[decCreate];
  282.         if pos('D',a)>0 then DebugFlags:=DebugFlags+[decDesign];
  283.         if pos('L',a)>0 then DebugFlags:=DebugFlags+[decLoaded];
  284.         if pos('U',a)>0 then DebugFlags:=DebugFlags+[decUpdate];
  285.         if pos('I',a)>0 then DebugFlags:=DebugFlags+[decInsert];
  286.         if pos('R',a)>0 then DebugFlags:=DebugFlags+[decRemove];
  287.         if pos('P',a)>0 then DebugFlags:=DebugFlags+[decPrint];
  288.         if pos('F',a)>0 then DebugFlags:=DebugFlags+[decFile];
  289.         if pos('N',a)>0 then DebugFlags:=DebugFlags+[decNotepad];
  290.         end;
  291.       end;
  292.     end;
  293. end;
  294.  
  295. {-----------------------------------------------------------------------------------------}
  296.  
  297. procedure FinalizeUnit;
  298. begin
  299.   if (decPrint in DebugFlags) or (decFile in DebugFlags) then {turn off}
  300.     AdjustDebugFlags([]); {stores back into global}
  301. end;
  302.  
  303. {-----------------------------------------------------------------------------------------}
  304. {-----------------------------------------------------------------------------------------}
  305.  
  306. Const
  307.   Initialized: boolean = False;
  308.   SaveExit: Pointer =nil;                    { Saves the old ExitProc }
  309.  
  310. procedure Finalize; far;
  311. begin
  312.   ExitProc := SaveExit;
  313.   FinalizeUnit;
  314. end;
  315.  
  316. procedure Initialize;
  317. begin
  318.   if not Initialized then begin
  319.     Initialized:=True;
  320.     SaveExit := ExitProc;
  321.     ExitProc := @Finalize;
  322.     InitializeUnit;
  323.     end;
  324. end;
  325.  
  326. initialization
  327.   Initialize;
  328. end.
  329.  
  330.  
  331.